package custom_http

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

func HttpPost[T any, B any](url string, headers map[string]string, requestBody B) (T, error) {
	var zero T

	// 序列化请求体
	jsonBody, err := json.Marshal(requestBody)
	if err != nil {
		return zero, fmt.Errorf("请求体序列化失败: %w", err)
	}

	// 创建带超时的 client
	client := &http.Client{
		Timeout: 10 * time.Second,
	}

	// 创建 POST 请求
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody))
	if err != nil {
		return zero, fmt.Errorf("创建请求失败: %w", err)
	}

	// 设置 Header
	if headers != nil {
		for key, value := range headers {
			req.Header.Set(key, value)
		}
	}

	// 如果没有设置 Content-Type，且有请求体，则默认设为 application/json
	if req.Header.Get("Content-Type") == "" {
		req.Header.Set("Content-Type", "application/json")
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return zero, fmt.Errorf("发起请求失败: %w", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return zero, fmt.Errorf("读取响应失败: %w", err)
	}

	// 检查状态码（可选：根据业务决定是否只接受 2xx）
	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		return zero, fmt.Errorf("HTTP 请求失败，状态码: %d, 响应: %s", resp.StatusCode, string(body))
	}

	// 解析响应为 T
	var result T
	if err := json.Unmarshal(body, &result); err != nil {
		return zero, fmt.Errorf("响应 JSON 解析失败: %w", err)
	}

	return result, nil
}
